
#include "apdu_lib_file_mgr.h"
#include "apdu_lib_common.h"

#include "../apdu.core/apdu.h"

#include "../../mk_lib/mk_auto_ptr.h"
#include "../../mk_lib/mk_utility.h"

#include <stdlib.h>
#include <string.h>
#include "../apdu.algo/mac.h"

extern int	g_sw;
int app_create_file( HANDLE devHandle, int app_id, unsigned char * file_attrs, int attrs_size )
{
	apdu * newApdu  =  NULL;
	newApdu = get_apdu_mgr()->create_apdu_create_file(app_id, file_attrs, attrs_size);

	mk_auto_ptr<apdu> ap(newApdu);

	
	if( 0 != get_dev_mgr()->transmit_apdu(devHandle,newApdu, &g_sw))
	{
		return 1;
	}

	if(g_sw != 0x9000)
	{
		return 2;
	}

	return 0;
}

int app_delete_file( HANDLE devHandle, int app_id, char * file_name )
{
	apdu * newApdu  =  NULL;
	newApdu = get_apdu_mgr()->create_apdu_delete_file(app_id, file_name);

	mk_auto_ptr<apdu> ap(newApdu);

	
	if( 0 != get_dev_mgr()->transmit_apdu(devHandle,newApdu, &g_sw))
	{
		return 1;
	}

	if(g_sw != 0x9000)
	{
		return 2;
	}

	return 0;
	
}

int app_enum_files( HANDLE devHandle, int app_id, char * file_names, int * buff_size )
{
	apdu * newApdu  =  NULL;
	newApdu = get_apdu_mgr()->create_apdu_enum_files(app_id);

	mk_auto_ptr<apdu> ap(newApdu);

	
	if( 0 != get_dev_mgr()->transmit_apdu(devHandle,newApdu, &g_sw))
	{
		return 1;
	}

	if(g_sw != 0x9000 && g_sw != 0x6A9E)
	{
		return 2;
	}

	int data_len =0;
	unsigned char * pData = newApdu->get_response_data(&data_len);

	if(*buff_size < data_len)
	{
		return 3;
	}
	*buff_size = data_len;
	memcpy(file_names, pData, data_len);
	return 0;

}

int app_get_file_info( HANDLE devHandle, int app_id, char * file_name, unsigned int * file_size,
					  unsigned int * read_rights, unsigned int * write_rights )
{
	apdu * newApdu  =  NULL;
	newApdu = get_apdu_mgr()->create_apdu_get_file_info(app_id,  file_name);

	mk_auto_ptr<apdu> ap(newApdu);

	
	if( 0 != get_dev_mgr()->transmit_apdu(devHandle,newApdu, &g_sw))
	{
		return 1;
	}

	if(g_sw != 0x9000)
	{
		return 2;
	}

	int data_len =0;
	unsigned char * pData = newApdu->get_response_data(&data_len);

	if(data_len < 12)
	{
		return 3;
	}
	
	memcpy(file_size, pData, 4);
	memcpy(read_rights, pData + 4, 4);
	memcpy(write_rights, pData + 8, 4);

	mk_utility::reverse_bytes(file_size, 4);

	return 0;
}

int app_set_file_info(HANDLE devHandle, int app_id,  char * file_name, 
						unsigned char * file_attrs, int attrs_size)
{
	apdu * newApdu  =  NULL;
	newApdu = get_apdu_mgr()->create_apdu_set_file_info(app_id, file_name, file_attrs, attrs_size);

	mk_auto_ptr<apdu> ap(newApdu);

	if( 0 != get_dev_mgr()->transmit_apdu(devHandle,newApdu, &g_sw))
	{
		return 1;
	}

	if(g_sw != 0x9000)
	{
		return 2;
	}

	return 0;
}

int app_read_file( HANDLE devHandle, int app_id, char * file_name, 
				  int offset, int *read_len, unsigned char* pData )
{
	apdu * newApdu  =  NULL;
	newApdu = get_apdu_mgr()->create_apdu_read_file(app_id, offset, *read_len, file_name);

	mk_auto_ptr<apdu> ap(newApdu);

	
	if( 0 != get_dev_mgr()->transmit_apdu(devHandle,newApdu, &g_sw))
	{
		return 1;
	}

	if(g_sw != 0x9000)
	{
		return 2;
	}

	int data_len = 0;
	unsigned char * pBuff = newApdu->get_response_data(&data_len);
	
	*read_len = data_len;
	memcpy(pData, pBuff, data_len);

	return 0;

}

int app_write_file( HANDLE devHandle, int app_id, char * file_name, int offset,
				   unsigned char * write_data, int write_len )
{
	apdu * newApdu  =  NULL;
	newApdu = get_apdu_mgr()->create_apdu_write_file(app_id, offset, file_name, write_data, write_len);

	mk_auto_ptr<apdu> ap(newApdu);

	
	if( 0 != get_dev_mgr()->transmit_apdu(devHandle,newApdu, &g_sw))
	{
		return 1;
	}

	if(g_sw != 0x9000)
	{
		return 2;
	}

	return 0;
}

int app_set_current_file_pos( HANDLE devHandle, int pos )
{
	apdu * newApdu  =  NULL;
	newApdu = get_apdu_mgr()->create_apdu_set_current_file_pos(pos);

	mk_auto_ptr<apdu> ap(newApdu);

	if( 0 != get_dev_mgr()->transmit_apdu(devHandle,newApdu, &g_sw))
	{
		return 1;
	}

	if(g_sw != 0x9000)
	{
		return 2;
	}

	return 0;
}

int app_crypt_read_file(HANDLE devHandle, int app_id, int container_id, int key_id, char * file_name, 
						int offset, int *read_len, unsigned char* pData, int is_final)
{
	apdu * newApdu  =  NULL;
	newApdu = get_apdu_mgr()->create_apdu_crypt_read_file(app_id, container_id, key_id, offset,
							*read_len, file_name, is_final);

	mk_auto_ptr<apdu> ap(newApdu);


	if( 0 != get_dev_mgr()->transmit_apdu(devHandle,newApdu, &g_sw))
	{
		return 1;
	}

	if(g_sw != 0x9000)
	{
		return 2;
	}

	int data_len = 0;
	unsigned char * pBuff = newApdu->get_response_data(&data_len);

	*read_len = data_len;
	memcpy(pData, pBuff, data_len);

	return 0;
}

int app_crypt_write_file( HANDLE devHandle, int app_id, int container_id, int key_id, char * file_name, 
						 int offset, unsigned char * write_data, int write_len, int is_final)
{
	apdu * newApdu  =  NULL;
	newApdu = get_apdu_mgr()->create_apdu_crypt_write_file(app_id, container_id, key_id, offset, file_name, 
				write_data, write_len, is_final);

	mk_auto_ptr<apdu> ap(newApdu);

	if( 0 != get_dev_mgr()->transmit_apdu(devHandle,newApdu, &g_sw))
	{
		return 1;
	}

	if(g_sw != 0x9000)
	{
		return 2;
	}

	return 0;
}
